From c1c0a2f39a8ac2a12792a17a6b1e2afc406caa83 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 5 Jun 2005 10:11:05 +0000 Subject: [PATCH] bitkeeper revision 1.1674 (42a2cfb9WFgnh2K4Xr5ev3pSEASVbw) Extend EVTCHNOP_alloc_unbound to allocate a specified port, if non-zero value is passed in. Signed-off-by: Keir Fraser --- tools/libxc/xc_evtchn.c | 5 ++-- tools/python/xen/lowlevel/xc/xc.c | 7 +++--- xen/common/event_channel.c | 37 ++++++++++++++++++++++-------- xen/include/public/event_channel.h | 7 +++--- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c index 9371e61261..8ee2fd11ee 100644 --- a/tools/libxc/xc_evtchn.c +++ b/tools/libxc/xc_evtchn.c @@ -39,8 +39,9 @@ int xc_evtchn_alloc_unbound(int xc_handle, int rc; op.cmd = EVTCHNOP_alloc_unbound; - op.u.alloc_unbound.dom = (domid_t)dom; - + op.u.alloc_unbound.dom = (domid_t)dom; + op.u.alloc_unbound.port = (port != NULL) ? *port : 0; + if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) { if ( port != NULL ) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index c23bc461e1..9b35ded02a 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -494,11 +494,12 @@ static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self, XcObject *xc = (XcObject *)self; u32 dom; - int port; + int port = 0; - static char *kwd_list[] = { "dom", NULL }; + static char *kwd_list[] = { "dom", "port", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, + &dom, &port) ) return NULL; if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 ) diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 75353209f9..6f6e707667 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -35,6 +35,8 @@ #define evtchn_from_port(d,p) \ (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)]) +#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 ) + static int get_free_port(struct domain *d) { struct evtchn *chn; @@ -61,30 +63,48 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) { struct evtchn *chn; struct domain *d = current->domain; - int port; + int port = alloc->port; + long rc = 0; spin_lock(&d->evtchn_lock); - if ( (port = get_free_port(d)) >= 0 ) + /* Obtain, or ensure that we already have, a valid . */ + if ( port == 0 ) { - chn = evtchn_from_port(d, port); + if ( (port = get_free_port(d)) < 0 ) + ERROR_EXIT(port); + } + else if ( !port_is_valid(d, port) ) + ERROR_EXIT(-EINVAL); + chn = evtchn_from_port(d, port); + + /* Validate channel's current state. */ + switch ( chn->state ) + { + case ECS_FREE: chn->state = ECS_UNBOUND; chn->u.unbound.remote_domid = alloc->dom; + break; + + case ECS_UNBOUND: + if ( chn->u.unbound.remote_domid != alloc->dom ) + ERROR_EXIT(-EINVAL); + break; + + default: + ERROR_EXIT(-EINVAL); } + out: spin_unlock(&d->evtchn_lock); - if ( port < 0 ) - return port; - alloc->port = port; - return 0; + return rc; } static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) { -#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 ) struct evtchn *chn1, *chn2; struct domain *d1, *d2; int port1 = bind->port1, port2 = bind->port2; @@ -217,7 +237,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) bind->port2 = port2; return rc; -#undef ERROR_EXIT } diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h index b00cda66c4..e787a0524a 100644 --- a/xen/include/public/event_channel.h +++ b/xen/include/public/event_channel.h @@ -10,15 +10,16 @@ #define __XEN_PUBLIC_EVENT_CHANNEL_H__ /* - * EVTCHNOP_alloc_unbound: Allocate a fresh local port and prepare - * it for binding to . + * EVTCHNOP_alloc_unbound: Prepare a local port for binding to . + * may be wildcarded by setting to zero, in which case a fresh port + * will be allocated, and the field filled in on return. */ #define EVTCHNOP_alloc_unbound 6 typedef struct { /* IN parameters */ domid_t dom; /* 0 */ u16 __pad; - /* OUT parameters */ + /* IN/OUT parameters */ u32 port; /* 4 */ } PACKED evtchn_alloc_unbound_t; /* 8 bytes */ -- 2.30.2